home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / disk utilities / backup / backup_restore / backup_src_v3.20.lha / NextFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-30  |  15.6 KB  |  705 lines

  1. // NextFile.c
  2. // 28 Jul 1996 18:35:19
  3.  
  4. #ifndef    BACKUP_INCLUDE
  5. #include "IncludeAll.c"
  6. #endif
  7. #include "Backup.h"
  8. #include "FileSelect.h"
  9. #include "Backup_proto.h"
  10. #include "BackupStrings.h"
  11.  
  12. // #define    d(x)    x
  13. #define    d(x)        ;
  14.  
  15.  
  16. #define    USE_EXALL    0        // wenn TRUE, dann wird ExAll() zum Scannen benutzt
  17.  
  18. #define    EXALL_BUFFSIZE    65536l        // Buffergröße für ExAll()
  19.  
  20.  
  21. static void DeleteDir(struct MinList *List);
  22. static void DeleteDirEntry(struct DirEntry *Dir);
  23. static struct FSDir *NextFSDir(struct NextFileInfo *Info);
  24. static struct FSDirEntry *NextFSEntry(struct NextFileInfo *Info, struct FSDir **theDir);
  25. static BOOL ExamineName(const char *Name, struct FileInfoBlock *fib);
  26. static BOOL NextFSFile(struct NextFileInfo *Info, struct FileInfoBlock *fib);
  27. static BOOL NextDEFile(struct NextFileInfo *Info, struct FileInfoBlock *fib,
  28.             struct MinList *DirList);
  29. static struct DirEntry *NewSubDir(struct DirEntry *Parent, const char *name, BOOL temp);
  30. static BOOL FileMatch(struct BackupOptions *Opt, struct FileInfoBlock *fib, BOOL TellSkips);
  31. static BOOL FibIsFile(const struct FileInfoBlock *fib, BPTR DirLock);
  32. static BOOL NFExNext(struct NextFileInfo *nfInfo, struct FileInfoBlock *fib);
  33.  
  34.  
  35. // aus Backup.c
  36. extern struct BackupOptions myOptions;        // Einstellungen für die aktuelle Sicherung
  37. extern char __far NormalizedAktPath[FMSIZE];    // AktPath normalisiert
  38.  
  39.  
  40. BOOL NextFileAbort;        // Abbruch-Flag für NextFile
  41.  
  42.  
  43. void CleanupNextFileInfo(struct NextFileInfo *Info)
  44. {
  45.     ASSERT_VALID(Info);
  46.  
  47.     if (Info->nfi_eaControl && Info->nfi_eaBuffer && Info->nfi_eaMore)
  48.         {
  49.         // ExAll() war noch nicht fertig
  50.         ExAllEnd(Info->nfi_DirLock, Info->nfi_eaBuffer, 
  51.                 EXALL_BUFFSIZE, ED_COMMENT, Info->nfi_eaControl);
  52.         }
  53.     if (Info->nfi_eaControl)
  54.         {
  55.         FreeDosObject(DOS_EXALLCONTROL, Info->nfi_eaControl);
  56.         Info->nfi_eaControl = NULL;
  57.         }
  58.     if (Info->nfi_eaBuffer)
  59.         {
  60.         free(Info->nfi_eaBuffer);
  61.         Info->nfi_eaBuffer = NULL;
  62.         }
  63.     if (Info->nfi_DirLock != NULL)
  64.         {
  65.         UnLock(Info->nfi_DirLock);
  66.         Info->nfi_DirLock = NULL;
  67.         }
  68.  
  69.     d(kprintf("deleting Directory tree\n");)
  70.     DeleteDir(&Info->nfi_FirstDir);    // Directory-Baum auflösen
  71. }
  72.  
  73.  
  74. // Angelegten Directory-Baum wieder auflösen
  75. static void DeleteDir(struct MinList *List)
  76. {
  77.     struct DirEntry *dir;
  78.  
  79.     ASSERT_VALID(List);
  80.     d(kprintf("Beginn DeleteDir  dir=%08lx\n", dir);)
  81.  
  82.     while (!IsListEmpty((struct List *) List))
  83.         {
  84.         dir = (struct DirEntry *) List->mlh_Head;
  85.  
  86.         DeleteDir(&dir->Sub);
  87.         DeleteDirEntry(dir);
  88.         }
  89.     d(kprintf("End DeleteDir\n");)
  90. }
  91.  
  92.  
  93. static void DeleteDirEntry(struct DirEntry *Dir)
  94. {
  95.     ASSERT_VALID(Dir);
  96.  
  97.     Remove((struct Node *) Dir);
  98.  
  99.     if (Dir->Temporary)
  100.         free(Dir);
  101. }
  102.  
  103.  
  104. void SetupNextFileInfo(struct NextFileInfo *Info, struct BackupOptions *Opt,
  105.         void (*DirDisp)())
  106. {
  107.     ASSERT_VALID(Info);
  108.     ASSERT_VALID(Opt);
  109.  
  110.     Info->nfi_DirLock = NULL;
  111.  
  112.     Info->nfi_FSDirIndex = 0;
  113.     Info->nfi_FSDirListDone = FALSE;
  114.     Info->nfi_VisibleIndex = 0;
  115.     Info->nfi_Dir = NULL;
  116.  
  117.     Info->nfi_eaControl = NULL;
  118.     Info->nfi_eaBuffer = NULL;
  119.     Info->nfi_eaData = NULL;
  120.     Info->nfi_eaMore = FALSE;
  121.  
  122.     NewList((struct List *) &Info->nfi_FirstDir);
  123.     Info->nfi_Opt = Opt;
  124.  
  125.     Info->nfi_DirDisplay = DirDisp;
  126.  
  127.     NextFileAbort = FALSE;
  128.  
  129.     InitSearchPattern(Opt);
  130.  
  131. #if USE_EXALL
  132.     Info->nfi_eaControl = AllocDosObject(DOS_EXALLCONTROL, NULL);
  133.     Info->nfi_eaBuffer = malloc(EXALL_BUFFSIZE); 
  134.  
  135.     Info->nfi_eaControl->eac_LastKey = 0;
  136. #endif
  137. }
  138.  
  139.  
  140. static struct FSDir *NextFSDir(struct NextFileInfo *Info)
  141. {
  142.     struct FSDir *Dir = NULL;
  143.     struct DirEntry *aktdir;
  144.  
  145.     ASSERT_VALID(Info);
  146.  
  147.     // Neues Directory suchen
  148.     while (!Info->nfi_FSDirListDone && (Dir == NULL || (ManualSelectCount(Dir) == 0)))
  149.         {
  150.         Info->nfi_FSDirListDone = Info->nfi_FSDirIndex >= Info->nfi_Opt->bo_FSDirCount;
  151.  
  152.         if (Info->nfi_FSDirListDone)
  153.             Dir = NULL;
  154.         else
  155.             Dir = Info->nfi_Opt->bo_FSDirList[Info->nfi_FSDirIndex++];
  156.         }
  157.  
  158.     if (Dir)
  159.         {
  160.         aktdir = NewDir(&Info->nfi_FirstDir, Dir->fsd_Name, 1);
  161.         SetupNewDir(Info, "", aktdir);
  162.  
  163.         if (Info->nfi_DirDisplay)
  164.             (*Info->nfi_DirDisplay)(aktdir);
  165.         aktdir->Done = TRUE;    // Dir in NextDEFile() nicht bearbeiten!
  166.         }
  167.  
  168.     return Dir;
  169. }
  170.  
  171.  
  172. static struct FSDirEntry *NextFSEntry(struct NextFileInfo *Info,
  173.         struct FSDir **theDir)
  174. {
  175.     struct FSDirEntry *FSe;
  176.  
  177.     ASSERT_VALID(Info);
  178.     ASSERT_VALID(theDir);
  179.  
  180.     do    {
  181.         if (Info->nfi_Dir == NULL)
  182.             {
  183.             // Neues Directory suchen
  184.             Info->nfi_Dir = NextFSDir(Info);
  185.  
  186.             Info->nfi_VisibleIndex = 0;
  187.             }
  188.  
  189.         // Ausgang wenn alle Directories durch
  190.         if (Info->nfi_Dir == NULL)
  191.             return NULL;
  192.  
  193.         do    {
  194.             // nächsten selektierten Eintrag suchen
  195.  
  196.             if (Info->nfi_VisibleIndex < Info->nfi_Dir->fsd_DirCount)
  197.                 FSe = Info->nfi_Dir->fsd_EntryList[Info->nfi_VisibleIndex++];
  198.             else
  199.                 {
  200.                 Info->nfi_Dir = NULL;
  201.                 FSe = NULL;
  202.                 }
  203.             } while (FSe && (FSe->fse_Selected != ST_Selected));
  204.         } while (FSe == NULL);
  205.  
  206.     if (FSe)
  207.         *theDir = Info->nfi_Dir;
  208.  
  209.     return FSe;
  210. }
  211.  
  212.  
  213. BOOL NextFile(struct NextFileInfo *Info, struct FileInfoBlock *fib)
  214. {
  215.     BOOL Result;
  216.  
  217.     ASSERT_VALID(Info);
  218.     ASSERT_VALID(fib);
  219.  
  220.     Result = (BOOL) (NextFSFile(Info, fib) || NextDEFile(Info, fib, &Info->nfi_FirstDir));
  221.  
  222. #ifdef NFDEBUG
  223.     if (Result)
  224.         printf("%6ld %8ld %s\n", fib->fib_DirEntryType, fib->fib_Size, fib->fib_FileName);
  225. #endif
  226.  
  227.     return Result;
  228. }
  229.  
  230.  
  231. static BOOL ExamineName(const char *Name, struct FileInfoBlock *fib)
  232. {
  233.     BPTR FileLock;
  234.     BOOL found;
  235.  
  236.     ASSERT_VALID(Name);
  237.     ASSERT_VALID(fib);
  238.  
  239.     FileLock = Lock((STRPTR) Name, ACCESS_READ);
  240.     found = FileLock && Examine(FileLock, fib);
  241.     if (FileLock)
  242.         UnLock(FileLock);
  243.  
  244.     return found;
  245. }
  246.  
  247.  
  248. static BOOL NextFSFile(struct NextFileInfo *Info, struct FileInfoBlock *fib)
  249. {
  250.     struct FSDir *Dir;
  251.     struct FSDirEntry *FSe;
  252.     char *Name;
  253.     BOOL found;
  254.  
  255.     ASSERT_VALID(Info);
  256.     ASSERT_VALID(fib);
  257.  
  258.     do    {
  259.         FSe = NextFSEntry(Info, &Dir);
  260.         found = FALSE;
  261.         if (FSe)
  262.             {
  263.             Name = ConcatDirName(Dir->fsd_Name, FSe->fse_Name);
  264.  
  265.             switch (FSe->fse_Typ)
  266.                 {
  267.             case Device:
  268.                 // Partition sichern
  269.                 fib->fib_DirEntryType = LONG_MIN;
  270.                 fib->fib_Size = FSe->fse_Size;
  271.                 fib->fib_NumBlocks = ~0;
  272.                 DateStamp(&fib->fib_Date);
  273.                 stccpy(fib->fib_FileName, FSe->fse_Name, sizeof(fib->fib_FileName));
  274.                 strcpy(fib->fib_Comment, "");
  275.                 found = TRUE;
  276.                 break;
  277.  
  278.             case HardLinkDir:
  279.                 if (Info->nfi_Opt->bo_SaveHardLinks)
  280.                     {
  281.                     // behandeln als Subdirectory
  282.                     if (ManualSelectCount(SearchFSDir(Name)) == 0)
  283.                         NewDir(&Info->nfi_FirstDir, Name, 1);
  284.                     }
  285.                 else
  286.                     {
  287.                     // behandeln als Link
  288.                     found = ExamineName(Name, fib);
  289.                     strcpy(fib->fib_FileName, FSe->fse_Name);
  290.                     }
  291.                 fib->fib_DirEntryType = ST_LINKDIR;
  292.                 break;
  293.  
  294.             case Directory:
  295.             case Assign:
  296.             case Volume:
  297.                 // SubDir nur eintragen wenn nicht schon
  298.                 // explizit erwähnt und dort manuell markiert!
  299.                 if (ManualSelectCount(SearchFSDir(Name)) == 0
  300.                     && ManualSelectCount(FSe->fse_Contents) == 0)
  301.                     {
  302.                     NewDir(&Info->nfi_FirstDir, Name, 1);
  303.                     }
  304.                 break;
  305.  
  306.             case SoftLinkDir:
  307.                 if (Info->nfi_Opt->bo_SaveSoftLinks)
  308.                     {
  309.                     // behandeln als Subdirectory
  310.                     if (ManualSelectCount(SearchFSDir(Name)) == 0)
  311.                         NewDir(&Info->nfi_FirstDir, Name, 1);
  312.                     }
  313.                 else
  314.                     {
  315.                     // behandeln als Link
  316.                     found = ExamineName(Name, fib);
  317.                     strcpy(fib->fib_FileName, FSe->fse_Name);
  318.                     }
  319.                 fib->fib_DirEntryType = ST_SOFTLINK;
  320.                 break;
  321.  
  322.             case SoftLinkFile:
  323.                 found = ExamineName(Name, fib);
  324.                 strcpy(fib->fib_FileName, FSe->fse_Name);
  325.                 fib->fib_DirEntryType = ST_SOFTLINK;
  326.                 break;
  327.  
  328.             case HardLinkFile:
  329.                 found = ExamineName(Name, fib);
  330.                 fib->fib_DirEntryType = ST_LINKFILE;
  331.                 stccpy(fib->fib_FileName, FSe->fse_Name, sizeof(fib->fib_FileName));
  332.                 break;
  333.             case File:
  334.                 found = ExamineName(Name, fib);
  335.                 break;
  336.                 }
  337.  
  338.             free(Name);
  339.             }
  340.         } while (FSe && !found);
  341.  
  342.     return found;
  343. }
  344.  
  345.  
  346. static BOOL NextDEFile(struct NextFileInfo *Info, struct FileInfoBlock *fib,
  347.             struct MinList *DirList)
  348. {
  349.     static struct FileInfoBlock __aligned DirFib;
  350.     struct DirEntry *aktdir;
  351.     BOOL found = FALSE;
  352.  
  353.     ASSERT_VALID(Info);
  354.     ASSERT_VALID(fib);
  355.     ASSERT_VALID(DirList);
  356.  
  357.     if (IsListEmpty((struct List *) DirList) || Info->nfi_Opt->bo_IncludeFile.RawName[0] == '\0')
  358.         return FALSE;
  359.  
  360.     aktdir = (struct DirEntry *) DirList->mlh_Head;    // erster Eintrag in der Liste
  361.  
  362.     if (!aktdir->Done)
  363.         {
  364.         if (aktdir->Virgin)
  365.             {
  366.             SetupNewDir(Info, Info->nfi_Opt->bo_IncludeFile.RawName, aktdir);
  367.             if (Info->nfi_DirDisplay)
  368.                 (*Info->nfi_DirDisplay)(aktdir);
  369.  
  370.             found  = Examine(Info->nfi_DirLock, &DirFib); // Liefert immer das aktuelle Directory
  371.  
  372. #if USE_EXALL
  373.             // ein neuer ExAll() Scan beginnt hier (neues Directory)
  374.             Info->nfi_eaControl->eac_LastKey = 0;
  375.             ExAllNFInfo(Info, ED_COMMENT);
  376. #endif
  377.             *fib = DirFib;
  378.  
  379.             if (found)
  380.                 {
  381.                 if (FileMatch(Info->nfi_Opt, fib, Info->nfi_TellSkips))
  382.                     {
  383.                     fib->fib_FileName[0] = '\0';    // Name des Directories steckt schon in AktPath
  384.                     found = TRUE;
  385.  
  386.                     return found;
  387.                     }
  388.                 else
  389.                     found = NFExNext(Info, fib);
  390.                 }
  391.  
  392.             aktdir->Done |= !found;
  393.             }
  394.         else if (Info->nfi_DirLock)
  395.             found = NFExNext(Info, fib);
  396.  
  397.         if (found)
  398.             aktdir->Contents++;
  399.  
  400.         // Subdirectories und nicht ausgewählte Files überspringen :
  401.         // Link-Dir's (Soft oder Hard) werden je nach den Flags bo_SaveSoftLinks
  402.         // und bo_SaveHardLinks behandelt. Ist das entsprechende Flag gesetzt,
  403.         // dann werden die Links als Files behandelt.
  404.  
  405.         while (found && !NextFileAbort && ( !FibIsFile(fib, Info->nfi_DirLock)
  406.                   || !FileMatch(Info->nfi_Opt, fib, Info->nfi_TellSkips) ))
  407.             {
  408.             if (Info->nfi_Opt->bo_IncludeSubDirs && fib->fib_DirEntryType > 0)
  409.                 // Subdirectories nicht zurückmelden, sondern merken
  410.                 {
  411.                 NewSubDir(aktdir, fib->fib_FileName, 1);
  412.                 }
  413.             found = NFExNext(Info, fib);
  414.  
  415.             chkinput();
  416.             }
  417.  
  418.         aktdir->Done |= !found;
  419.         }
  420.  
  421.     if (!found && !NextFileAbort && !IsListEmpty((struct List *) &aktdir->Sub))
  422.         {
  423.         // Subdirectories von aktdir durchsuchen
  424.         found = NextDEFile(Info, fib, &aktdir->Sub);
  425.         }
  426.  
  427.     if (!found && !NextFileAbort && !IsListEmpty((struct List *) DirList))
  428.         {
  429.         DeleteDirEntry(aktdir);
  430.         found = NextDEFile(Info, fib, DirList);
  431.         }
  432.  
  433.     return found;
  434. }
  435.  
  436.  
  437.  
  438. static struct DirEntry *NewSubDir(struct DirEntry *Parent, const char *name, BOOL temp)
  439. {
  440.     struct DirEntry *akt;
  441.  
  442.     ASSERT_VALID(Parent);
  443.     ASSERT_VALID(name);
  444.  
  445.     akt = NewDir(&Parent->Sub, name, temp);
  446.     akt->Root = Parent;
  447.  
  448.     return akt;
  449. }
  450.  
  451.  
  452. BOOL FSFileMatch(struct BackupOptions *Opt, const struct FSDirEntry *FSe)
  453. {
  454.     struct FileInfoBlock fib;
  455.  
  456.     ASSERT_VALID(Opt);
  457.     ASSERT_VALID(FSe);
  458.  
  459.     fib.fib_Size = FSe->fse_Size;
  460.     fib.fib_Protection = FSe->fse_Protection;
  461.     fib.fib_Date = FSe->fse_Date;
  462.     stccpy(fib.fib_FileName, FSe->fse_Name, sizeof(fib.fib_FileName));
  463.  
  464.     InitSearchPattern(Opt);
  465.  
  466.     return FileMatch(Opt, &fib, FALSE);
  467. }
  468.  
  469.  
  470. static BOOL FileMatch(struct BackupOptions *Opt, struct FileInfoBlock *fib, BOOL TellSkips)
  471. {
  472.     char SkippedPath[FMSIZE];
  473.     ASSERT_VALID(Opt);
  474.     ASSERT_VALID(fib);
  475.  
  476.     // Protokollfile hier nicht mitsichern !
  477.     if (isProtFile(NormalizedAktPath, fib->fib_FileName))
  478.         {
  479.         stccpy(SkippedPath, NormalizedAktPath,  sizeof(SkippedPath));
  480.         AddPart(SkippedPath, fib->fib_FileName, sizeof(SkippedPath));
  481.  
  482.         if (TellSkips)
  483.             PostError(TRUE, MSGPRI_Info, GetString(MSG_FILE_SKIPPED), SkippedPath);
  484.         return FALSE;
  485.         }
  486.  
  487.     // DiskSave-File auch nicht mitsichern
  488.     if (isDiskSaveFile(NormalizedAktPath, fib->fib_FileName))
  489.         {
  490.         stccpy(SkippedPath, NormalizedAktPath,  sizeof(SkippedPath));
  491.         AddPart(SkippedPath, fib->fib_FileName, sizeof(SkippedPath));
  492.  
  493.         if (TellSkips)
  494.             PostError(TRUE, MSGPRI_Info, GetString(MSG_FILE_SKIPPED), SkippedPath);
  495.         return FALSE;
  496.         }
  497.  
  498.     if (Opt->bo_UseGrepPattern && Opt->bo_IncludeFile.isParsed)
  499.         {
  500.         if (!MatchPatternNoCase(Opt->bo_IncludeFile.ParsedPattern, fib->fib_FileName))
  501.             return FALSE;
  502.         }
  503.     else
  504.         {
  505.         if (!FileNamePatternMatch(Opt->bo_IncludeFile.RawName, fib))
  506.             return FALSE;
  507.         }
  508.  
  509.     // hier evtl. abkürzen, da meist sowieso bo_ExcludeFile leer ist!
  510.     if (Opt->bo_ExcludeFile.RawName[0])
  511.         {
  512.         if (Opt->bo_UseGrepPattern && Opt->bo_ExcludeFile.isParsed)
  513.             {
  514.             if (MatchPatternNoCase(Opt->bo_ExcludeFile.ParsedPattern, fib->fib_FileName))
  515.                 return FALSE;
  516.             }
  517.         else
  518.             {
  519.             if (FileNamePatternMatch(Opt->bo_ExcludeFile.RawName, fib))
  520.                 return FALSE;
  521.             }
  522.         }
  523.  
  524.     if (Opt->bo_UseArc == Set && !(fib->fib_Protection & FIBF_ARCHIVE))
  525.         return FALSE;
  526.  
  527.     if (Opt->bo_UseArc == Reset && (fib->fib_Protection & FIBF_ARCHIVE))
  528.         return FALSE;
  529.  
  530.     if ( Opt->bo_UseFirstDate && (fib->fib_Date.ds_Days < Opt->bo_FirstDate))
  531.         return FALSE;
  532.  
  533.     if ( Opt->bo_UseLastDate && (fib->fib_Date.ds_Days > Opt->bo_LastDate))
  534.         return FALSE;
  535.  
  536.     return TRUE;
  537. }
  538.  
  539.  
  540. // liefert TRUE wenn info->fib_FileName mit suchname übereinstimmt
  541. BOOL FileNamePatternMatch(char *suchname, const struct FileInfoBlock *info)
  542. {
  543.     BOOL cmperg = TRUE;
  544.     const char *fnp;
  545.     char c;
  546.  
  547.     ASSERT_VALID(info);
  548.     ASSERT_VALID0(suchname);
  549.  
  550.     if (suchname == NULL || *suchname == '\0')
  551.         return FALSE;    // nichts finden bei leerem Pattern
  552.  
  553.     fnp = info->fib_FileName;
  554.     while ( (c = *suchname) && cmperg)
  555.         {
  556.         ++suchname;
  557.  
  558.         switch (c)
  559.             {
  560.         case '?':
  561.             if (*fnp)
  562.                 fnp++;
  563.             break;
  564.         case '*':
  565.             if (*suchname == '\0')
  566.                 {
  567.                 // Ans Ende des Namens
  568.                 while (*fnp)
  569.                     fnp++;
  570.                 }
  571.             else
  572.                 {
  573.                 const char *found;
  574.                 char *str;
  575.                 char origc;
  576.  
  577.                 // Zeichen zählen in suchname bis zum Ende oder bis
  578.                 // zum nächsten Wildcard
  579.                 for (str=suchname; *str && *str != '?' && *str != '*'; str++);
  580.                 origc = *str;
  581.                 *str = '\0';    // Suchstring provisorisch abschließen
  582.  
  583.                 found = myindex(fnp, suchname);
  584.  
  585.                 if (found)
  586.                     {
  587.                     // Weiter ab Ende des gefundenen Stücks
  588.                     fnp = found + strlen(suchname);
  589.                     suchname = str;
  590.                     }
  591.                 else
  592.                     cmperg = FALSE;    // nicht gefunden !
  593.  
  594.                 *str = origc;    // Suchname restaurieren
  595.                 }
  596.             break;
  597.         default:
  598.             cmperg &= toupper(c) == toupper(*fnp);
  599.             fnp++;
  600.             }
  601.         }
  602.     
  603.     // Name muß auch zu Ende sein !
  604.     if (*fnp)
  605.         cmperg = FALSE;
  606.  
  607.     return cmperg;
  608. }
  609.  
  610.  
  611. const char *myindex(const char *s, const char *t)
  612. {
  613.     short i, j, k;
  614.  
  615.     ASSERT_VALID(s);
  616.     ASSERT_VALID(t);
  617.  
  618.     for (i=0; s[i]; i++)
  619.         {
  620.         for (j=i, k=0; t[k] && toupper(s[j]) == toupper(t[k]); j++, k++);
  621.         if (t[k] == '\0')
  622.             return &s[i];
  623.         }
  624.     return NULL;
  625. }
  626.  
  627.  
  628. static BOOL FibIsFile(const struct FileInfoBlock *fib, BPTR DirLock)
  629. {
  630.     BOOL result;
  631.  
  632.     ASSERT_VALID(fib);
  633.     ASSERT_VALID(BADDR(DirLock));
  634.  
  635.     switch (fib->fib_DirEntryType)
  636.         {
  637.     case ST_SOFTLINK:
  638.         result = myOptions.bo_SaveSoftLinks ?
  639.                 (SoftLinkType((STRPTR) fib->fib_FileName, DirLock) == SoftLinkFile) : 1;
  640.         break;
  641.     case ST_LINKFILE:
  642.         result = 1;
  643.         break;
  644.     case ST_LINKDIR:
  645.         result = !myOptions.bo_SaveHardLinks;
  646.         break;
  647.     default:
  648.         result = fib->fib_DirEntryType < 0;
  649.         }
  650.  
  651.     return result;
  652. }
  653.  
  654.  
  655. static BOOL NFExNext(struct NextFileInfo *nfInfo, struct FileInfoBlock *fib)
  656. {
  657.     BOOL found;
  658.  
  659. #if USE_EXALL
  660.     found = FALSE;
  661.  
  662.     while (NULL == nfInfo->nfi_eaData && nfInfo->nfi_eaMore)
  663.         {
  664.         ExAllNFInfo(nfInfo, ED_COMMENT);
  665.         }
  666.  
  667.     if (nfInfo->nfi_eaData)
  668.         {
  669.         // die gefundenen Werte werden in den FileInfoBlock eingetragen
  670.  
  671.         if (nfInfo->nfi_eaData->ed_Comment)
  672.             stccpy(fib->fib_Comment, nfInfo->nfi_eaData->ed_Comment, sizeof(fib->fib_Comment));
  673.         else
  674.             strcpy(fib->fib_Comment, "");
  675.  
  676.         stccpy(fib->fib_FileName, nfInfo->nfi_eaData->ed_Name, sizeof(fib->fib_FileName));
  677.  
  678.         fib->fib_Protection = nfInfo->nfi_eaData->ed_Prot;
  679.         fib->fib_Size = nfInfo->nfi_eaData->ed_Size;
  680.         fib->fib_DirEntryType = nfInfo->nfi_eaData->ed_Type;
  681.  
  682.         fib->fib_Date.ds_Days = nfInfo->nfi_eaData->ed_Days;
  683.         fib->fib_Date.ds_Minute = nfInfo->nfi_eaData->ed_Mins;
  684.         fib->fib_Date.ds_Tick = nfInfo->nfi_eaData->ed_Ticks;
  685.  
  686.         found = TRUE;
  687.  
  688.         nfInfo->nfi_eaData = nfInfo->nfi_eaData->ed_Next;
  689.         }
  690. #else
  691.     found = ExNext(nfInfo->nfi_DirLock, fib);
  692. #endif
  693.  
  694.     return found;
  695. }
  696.  
  697.  
  698. void ExAllNFInfo(struct NextFileInfo *NFInfo, long ExAllType)
  699. {
  700.     NFInfo->nfi_eaMore = ExAll(NFInfo->nfi_DirLock, NFInfo->nfi_eaBuffer, 
  701.         EXALL_BUFFSIZE, ExAllType, NFInfo->nfi_eaControl);
  702.  
  703.     NFInfo->nfi_eaData = NFInfo->nfi_eaControl->eac_Entries ? (struct ExAllData *) NFInfo->nfi_eaBuffer : NULL;
  704. }
  705.